﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace SceneManager.Processors
{
    public class NormalDepthColorProcessor : Processor
    {
        public List<DrawableObject> Objects { get; set; }

        private Effect normalDepthColorEffect;
        private Effect skinnedNormalDepthColorEffect;

        public NormalDepthColorProcessor(Game game, List<DrawableObject> objects) :  base(game)
        {
            Objects = objects;

            Outputs.Add("Normal", new RenderTarget2D(Game.GraphicsDevice, Game.GraphicsDevice.PresentationParameters.BackBufferWidth, Game.GraphicsDevice.PresentationParameters.BackBufferHeight, false, SurfaceFormat.Color, DepthFormat.Depth24));
            Outputs.Add("Depth", new RenderTarget2D(Game.GraphicsDevice, Game.GraphicsDevice.PresentationParameters.BackBufferWidth, Game.GraphicsDevice.PresentationParameters.BackBufferHeight, false, SurfaceFormat.Single, DepthFormat.None));
            Outputs.Add("Color", new RenderTarget2D(Game.GraphicsDevice, Game.GraphicsDevice.PresentationParameters.BackBufferWidth, Game.GraphicsDevice.PresentationParameters.BackBufferHeight, false, SurfaceFormat.Color, DepthFormat.Depth24));

            normalDepthColorEffect = Game.Content.Load<Effect>("Shaders/Default/NormalDepthColor");
            skinnedNormalDepthColorEffect = Game.Content.Load<Effect>("Shaders/Default/SkinnedNormalDepthColor");
        }

        public override void Process(Camera camera, GameTime gameTime)
        {
#if DEBUG
            stopwatch.Restart();
#endif

            normalDepthColorEffect.Parameters["FarPlane"].SetValue(camera.FarPlane);
            skinnedNormalDepthColorEffect.Parameters["FarPlane"].SetValue(camera.FarPlane);

            Game.GraphicsDevice.SetRenderTargets(Outputs["Normal"], Outputs["Depth"], Outputs["Color"]);
            Game.GraphicsDevice.BlendState = BlendState.Opaque;
            foreach (DrawableObject o in Objects)
            {
                if (o is ISkinnedObject) // FIXME
                    o.Effect = skinnedNormalDepthColorEffect;
                else
                    o.Effect = normalDepthColorEffect;
                o.Draw(camera, gameTime);
            }

#if DEBUG
            processTimes.Enqueue((int)stopwatch.ElapsedTicks);
            while (processTimes.Count > 60)
                processTimes.Dequeue();
#endif
        }
    }
}
